package com.example.websocket.config.core.json;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.TimeZone;

@Configuration
@Slf4j
public class JacksonConfig {

    @Autowired
    private ExtendFieldSerializerModifier extendFieldSerializerModifier;

    // 定义日期时间格式常量
    public static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    public static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern(DATE_TIME_FORMAT);

    // 自定义Date序列化器
    public static class CustomDateSerializer extends JsonSerializer<Date> {
        private static final SimpleDateFormat sdf = new SimpleDateFormat(DATE_TIME_FORMAT);

        @Override
        public void serialize(Date value, JsonGenerator gen, SerializerProvider provider) throws IOException {
            if (value != null) {
                gen.writeString(sdf.format(value));
            } else {
                gen.writeNull();
            }
        }
    }

    // 自定义Date反序列化器
    public static class CustomDateDeserializer extends JsonDeserializer<Date> {
        private static final SimpleDateFormat sdf = new SimpleDateFormat(DATE_TIME_FORMAT);

        @Override
        public Date deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
            String dateStr = p.getText();
            if (dateStr == null || dateStr.trim().isEmpty()) {
                return null;
            }
            try {
                return sdf.parse(dateStr);
            } catch (Exception e) {
                throw new IOException("日期格式错误，正确格式应为：" + DATE_TIME_FORMAT, e);
            }
        }
    }

    @Bean
    public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
        // 直接构建ObjectMapper而不是使用默认的，确保配置完全可控
        ObjectMapper objectMapper = new ObjectMapper();

        // 注册时间模块
        JavaTimeModule javaTimeModule = getTimeModule();
        objectMapper.registerModule(javaTimeModule);

        // 注册扩展字段序列化器
        objectMapper.registerModule(new SimpleModule().setSerializerModifier(extendFieldSerializerModifier));

        // 禁用时间戳序列化
        objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        // 设置时区
        objectMapper.setTimeZone(TimeZone.getTimeZone("GMT+8"));

        return new MappingJackson2HttpMessageConverter(objectMapper);
    }

    @Bean
    public Jackson2ObjectMapperBuilderCustomizer customizer() {
        return builder -> {
            // 配置时间序列化器
            builder.modules(getTimeModule());
            // 禁用默认的时间戳序列化
            builder.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
            // 显式指定时区为GMT+8，避免服务器时区影响
            builder.timeZone(TimeZone.getTimeZone("GMT+8"));

            log.info("Jackson配置初始化完成");
        };
    }

    // 构建时间模块
    private JavaTimeModule getTimeModule() {
        JavaTimeModule module = new JavaTimeModule();

        // 关键：注册LocalDateTime的序列化器和反序列化器
        module.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DATE_TIME_FORMATTER));
        module.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DATE_TIME_FORMATTER));

        // 配置Date类型
        module.addSerializer(Date.class, new CustomDateSerializer());
        module.addDeserializer(Date.class, new CustomDateDeserializer());

        // 配置其他类型
        module.addSerializer(Long.class, ToStringSerializer.instance);
        module.addSerializer(Long.TYPE, ToStringSerializer.instance);
        module.addSerializer(BigInteger.class, ToStringSerializer.instance);
        module.addSerializer(BigDecimal.class, ToStringSerializer.instance);

        return module;
    }
}
